﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;

namespace ReactiveCode.Statements
{
    using Observables;

    class IfStatement : ReactiveStatement, IStatementParent
    {
        ReactiveStatement _trueRule, _falseStatement, _actualStatement;
        IDisposable _subscription;
        List<ReactiveStatement> _children = new List<ReactiveStatement>();

        public IfStatement(ObservableFactory<IObservable<bool>> test, ReactiveStatement trueStatement, ReactiveStatement falseStatement)
        {
            Contract.Requires(test != null && trueStatement != null);

            if (trueStatement != null)
            {
                _trueRule = trueStatement;
                _children.Add(_trueRule);
                _trueRule.Parent = this;
            }
            if (falseStatement != null)
            {
                _falseStatement = falseStatement;
                _children.Add(_falseStatement);
                _falseStatement.Parent = this;
            }

            Contract.Assert(_children.Any());

            EnabledProperty.Subscribe(value =>
            {
                if (_actualStatement != null)
                    _actualStatement.Enabled = value;
            });
            _subscription = Extract(test).Subscribe(x =>
            {
                if (_trueRule != null)
                    _trueRule.Enabled = x && Enabled;
                if (_falseStatement != null)
                    _falseStatement.Enabled = !x && Enabled;
                _actualStatement = x ? _trueRule : _falseStatement;
            });
        }
        public override void Dispose()
        {
            base.Dispose();
            _subscription.Dispose();
            if (_trueRule != null)
                _trueRule.Dispose();
            if (_falseStatement != null)
                _falseStatement.Dispose();
        }

        #region IStatementParent Members

        IList<ReactiveStatement> IStatementParent.Children
        {
            get { return _children; }
        }

        #endregion
    }
}
